package com.crazypos.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.crazypos.constant.UserRoleConstant;
import com.crazypos.constant.UserTypeConstant;
import com.crazypos.dao.UserDao;
import com.crazypos.dao.UserRoleDao;
import com.crazypos.exceptions.MyException;
import com.crazypos.pojo.RoleEntity;
import com.crazypos.pojo.UserEntity;
import com.crazypos.pojo.UserRoleEntity;
import com.crazypos.pojo.bo.AdminCreateUserBO;
import com.crazypos.pojo.bo.AdminUpdateOwnerBO;
import com.crazypos.pojo.bo.GetUserListBO;
import com.crazypos.pojo.bo.UserLoginBO;
import com.crazypos.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;

import javax.jws.soap.SOAPBinding;
import java.util.List;

@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class UserService extends ServiceImpl<UserDao, UserEntity> implements IUserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private UserRoleDao userRoleDao;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    public Integer countUserByAccount(String account) {
        QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account", account);
        return userDao.selectCount(queryWrapper);
    }

    @Override
    public Integer countUserByEmail(String email) {
        QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("email", email);
        return userDao.selectCount(queryWrapper);
    }

    @Override
    public String userLoginAndCreateToken(UserLoginBO userLoginBO) throws Exception {
        String account = userLoginBO.getAccount();
        String password = userLoginBO.getPassword();

        QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account", account).eq("password", password);
        UserEntity userEntity = userDao.selectOne(queryWrapper);

        if (userEntity != null) {
//            String token = JWTTokenUtil.createToken(userEntity, 0);

//            return token;
        }
        return "";
    }

    @Override
    public UserEntity getUserByAccnount(String account) {
        QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account", account);
        return userDao.selectOne(queryWrapper);
    }

    @Override
    public List<RoleEntity> selectRolesByUserId(String userId) {
        return userDao.selectUserRoleByUserId(userId);
    }

    @Override
    public Integer countUserByAccountAndOrgId(String account, String organizationId) {
        QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account", account);
        queryWrapper.eq("organization_id", organizationId);
        return userDao.selectCount(queryWrapper);
    }

    @Override
    public Integer countUserByPinAndOrgId(String organizationId, String pin) {
        QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("pin", pin);
        queryWrapper.eq("organization_id", organizationId);
        return userDao.selectCount(queryWrapper);
    }

    /***
     * 管理员创建OWNER
     * @param createUserBO
     * @param userType
     * @param adminId
     */
    @Override
    @Transactional
    public void adminCreateUser(AdminCreateUserBO createUserBO, String userType, String adminId) {
        String organizationId = createUserBO.getOrganizationId();
        String userAccount = createUserBO.getAccount();
        String userPin = createUserBO.getPin();
        String password = createUserBO.getPassword();
        String confirmPassword = createUserBO.getConfirmPassword();
        if (!confirmPassword.equals(password)) {
            throw new MyException(500, "密码和确认密码输入不一致");
        }

        Integer isUserExist = countUserByAccount(userAccount);
        if (isUserExist > 0) {
            throw new MyException(500, "用户已经注册");
        }

        Integer isPinExist = countUserByPinAndOrgId(organizationId, userPin);
        if (isPinExist > 0) {
            throw new MyException(500, "PIN已经存在");
        }

        UserEntity userEntity = new UserEntity();

        BeanUtils.copyProperties(createUserBO, userEntity);
        userEntity.setPassword(bCryptPasswordEncoder.encode(createUserBO.getPassword()));
        userEntity.setAdminId(adminId);
        userEntity.setType(userType);
        userDao.insert(userEntity);

        UserRoleEntity userRoleEntity = new UserRoleEntity();
        userRoleEntity.setUserId(userEntity.getId());
        userRoleEntity.setRoleId(UserRoleConstant.OWNER);
        userRoleDao.insert(userRoleEntity);

    }

    @Override
    @Transactional
    public IPage<UserEntity> getUserList(GetUserListBO bo, String userType) {
        Integer startPage = bo.getStartPage();
        Integer pageSize = bo.getPageSize();
        if (startPage == null || startPage <= 0) {
            startPage = 1;
        }
        if (pageSize == null || pageSize <= 0) {
            pageSize = 10;
        }

        QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type", userType);

        Page<UserEntity> userEntityPage = new Page<>(startPage, pageSize);
        Page<UserEntity> result = userDao.selectPage(userEntityPage, queryWrapper);

        return result;
    }

    @Override
    @Transactional
    public void adminUpdateOwner(AdminUpdateOwnerBO bo) {
        QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", bo.getId())
                .eq("type", UserTypeConstant.OWNER);
        UserEntity originUser = userDao.selectOne(queryWrapper);
        if (originUser == null) {
            throw new MyException(500, "无法找到该账户");
        }

        UserEntity userEntity = new UserEntity();
        BeanUtils.copyProperties(bo, userEntity);

        userEntity.setPassword(null);
        userEntity.setPin(null);

        if (!StringUtils.isEmpty(bo.getPassword())) {
            if (!bo.getPassword().equals(bo.getConfirmPassword())) {
                throw new MyException(500, "两次密码输入不正确");
            }
            // 修改密码
            userEntity.setPassword(bCryptPasswordEncoder.encode(bo.getPassword()));
        }


        if (!StringUtils.isEmpty(bo.getPin())) {
            int count = userDao.selectCount(
                    new QueryWrapper<UserEntity>()
                            .eq("pin", bo.getPin())
                            .eq("organization_id", originUser.getOrganizationId())
                            .ne("id", originUser.getId())
            );
            if (count > 0) {
                throw new MyException(500, "PIN已经存在");
            }
            userEntity.setPin(bo.getPin());
        }

        userDao.update(userEntity, new QueryWrapper<UserEntity>().eq("id", originUser.getId()));
    }
}
